/*
 * @Author: 260156 260156@gree.com.cn
 * @Date: 2022-08-17 10:15:22
 * @LastEditors: 260156 260156@gree.com.cn
 * @LastEditTime: 2022-08-18 08:48:57
 * @FilePath: \gree-zst-web\src\utils\request\downloadIndex.ts
 * @Description:
 *
 * Copyright (c) 2022 by 260156 260156@gree.com.cn, All Rights Reserved.
 */
import axios from "axios";
import { ElMessage } from "element-plus";
import type {
  DownloadResult,
  DownloadRequestOptions,
  DownloadRequestResult,
} from "#/request";
import { requireLoginMessageBox } from "../helper";
import type { AxiosRequestConfig } from "axios";
import { DownloadRequestMethods } from "./RequestMehods";
import { downloadFile } from "./downloadFile";

const { VITE_BASE } = import.meta.env;

const axiosInstance = axios.create({
  baseURL: VITE_BASE,
  responseType: "blob",
});

interface ResponseMessage {
  desc: string;
}

axiosInstance.interceptors.response.use(
  async (response) => {
    const {
      data: responseData,
      status: responseStatus,
      statusText,
      headers: { "content-type": contentType },
    } = response;
    if (responseStatus === 200) {
      if (contentType.indexOf("application/octet-stream") < 0) {
        const responseMessageJson: string = await new Response(
          responseData
        ).text();
        const responseMessage: ResponseMessage =
          JSON.parse(responseMessageJson);
        const errorMsg = responseMessage.desc || statusText;
        // 登录过期
        if (responseData.status === 401) {
          localStorage.clear();
          sessionStorage.clear();
          requireLoginMessageBox({ message: responseData.desc });
          return Promise.reject(responseData.desc || statusText);
        } else {
          ElMessage.error(errorMsg);
          return Promise.reject(errorMsg);
        }
      } else {
        // application/json;charset=utf-8
        return response || {};
      }
    }
    ElMessage.error(statusText);
    return Promise.reject(statusText);
  },
  (error) => {
    let title = "其他错误";
    if (error.response) {
      const { status, statusText: message } = error.response;
      if (status >= 400 && status < 500) {
        title = `${status}: 请求错误`;
      } else if (status >= 500) {
        title = `${status}: 服务器错误`;
      }
      ElMessage.error(title + " - " + message);
      return Promise.reject(error.response);
    } else if (error.message) {
      ElMessage.error(error.message);
      return Promise.reject(error.message);
    } else {
      return Promise.reject(new Error("请求中断"));
    }
  }
);

/**
 * @description: 所有请求最后都会调用此方法
 * @param {AxiosRequestConfig} config: axios请求的参数
 * @param {?DownloadRequestOptions} options: 导出文件名及后缀
 *  {fileName, ext} 可传可不传，也可部分传参
 *  比如只传{fileName}
 *  默认导出文件名是：系统名 + 日期 + .xlsx
 * @return {*}
 */
const axiosRequest = async (
  config: AxiosRequestConfig,
  options?: DownloadRequestOptions
): Promise<DownloadRequestResult> => {
  try {
    const { data } = await axiosInstance.request<DownloadResult>(config);

    // 直接导出
    downloadFile({ data, ...(options || {}) });

    return Promise.resolve({
      status: 200,
      message: "success",
    });
  } catch (err) {
    const msg = {
      status: 500,
      message: err,
    };
    return Promise.reject(new Error(JSON.stringify(msg)));
  }
};

// 添加request/get/post/put/delete...
const myDownloadAxios = new DownloadRequestMethods(axiosRequest);

/**
 * @description: 导出文件
 * 使用方法：
 * myDownloadAxios.request(config, options)  —— 参数与方法axiosRequest一致
 * myDownloadAxios.get(config, options)
 * myDownloadAxios.post(config, options)
 * myDownloadAxios.delete(config, options)
 * myDownloadAxios.put(config, options)
 */
export default myDownloadAxios;
